package testing.utility;

import org.uispec4j.ComponentAmbiguityException;
import org.uispec4j.Panel;



//Classe per ottenere il sudoku dall'interfaccia swing
public class Matrice {

	public static String getMatrice(Panel main){		
		
		String descrittore = main.getDescription();
		descrittore= descrittore.substring(descrittore.indexOf("Crea nuovo")+13);
		descrittore = descrittore.replaceAll("<textBox text=", "");
		descrittore = descrittore.replaceAll("/>", "");
		descrittore = descrittore.replaceAll("</window>", "");
		descrittore = descrittore.replaceAll("\r\n|\r|\n", "");
		descrittore = descrittore.substring(1);
		descrittore = descrittore.replaceAll(" ", "0");
		descrittore = descrittore.replaceAll("\"", "");
				
		return descrittore;
	}
	
	public static int[][] getMatriceInt(String matrice){
		int[][] m = new int[9][9];
		matrice = matrice.replace(",", "");
		matrice = matrice.replace(" ", "0");
		matrice = matrice.replace("[", "");
		matrice = matrice.replace("]", "");
		
		for (int i=0; i<9; i++){
			for (int j=0; j<9; j++){
				m[i][j] = Character.getNumericValue((matrice.charAt(i*9+j)));
			}
		}
		
		return m;
		
	}
	
	public static boolean getCorrect(Panel main){
		String stato="";
		try{
			main.getTextBox().getText();
			return false;
		} catch (ComponentAmbiguityException e){
			stato = e.getMessage();
			stato = stato.substring(stato.indexOf("Stato del sudoku:")+18);
			stato = stato.substring(0, stato.length()-163);
			return !stato.contains("non corretto");
		}
		
	}
	
	public static boolean getRisolto(Panel main){
		String stato="";
		try{
			main.getTextBox().getText();
			return false;
		} catch (ComponentAmbiguityException e){
			stato = e.getMessage();
			stato = stato.substring(stato.indexOf("Stato del sudoku:")+18);
			stato = stato.substring(0, stato.length()-163);
			return !stato.contains("non risolto");
		}
		
	}
	
	//Metodo che verifica che il soduki sia COMPLETO e CORRETTO!
	public static boolean VerificaCompletezza(int sudoku[][]){
		boolean res = true;
		
		//verifica se sono presenti elementi =0 (completezza )
		for (int i = 0; i < 9; i++){
			for (int j = 0; j < 9; j++){
				if(sudoku[i][j]==0) res = false;
			}
		}
		
		//verifica anche la correttezza
		if(res) res=VerificaCorrettezza(sudoku);
		
		return res;
	}
	
	//Metodo che verifica la correttezza del sudoku
	public static boolean VerificaCorrettezza(int sudoku[][]){
		
		for (int i = 0; i < 9; i++) {
            if(!checkColumn(i,sudoku) || !checkLine(i,sudoku) || !checkGroup(i,sudoku)){
                return false;
            }
        }
		
		return true;
	}
	
	//controllo correttezza linee
    private static boolean checkLine(int pLine, int sudoku[][]) {
        int find;
        for (int i = 0; i < 9; i++) {
            find = 0;
            for (int j = 0; j < 9; j++) {
                if (sudoku[pLine][j] == (i + 1)) {
                    find++;
                }
            }
            if (find > 1) {
                return false;
            }
        }
        return true;
    }
    
   //controllo correttezza colonne
    private static boolean checkColumn(int pColumn, int sudoku[][]) {
        int find;
        for (int i = 0; i < 9; i++) {
            find = 0;
            for (int j = 0; j < 9; j++) {
                if (sudoku[j][pColumn] == (i + 1)) {
                    find++;
                }
            }
            if (find > 1) {
                return false;
            }
        }
        return true;
    }

    //controllo correttezza gruppi
    private static boolean checkGroup(int pGroup, int sudoku[][]) {
        int[] coords = new int[2];
        switch (pGroup) {
            case 0:
                coords[0] = 0;
                coords[1] = 0;
                break;
            case 1:
                coords[0] = 0;
                coords[1] = 3;
                break;
            case 2:
                coords[0] = 0;
                coords[1] = 6;
                break;
            case 3:
                coords[0] = 3;
                coords[1] = 0;
                break;
            case 4:
                coords[0] = 3;
                coords[1] = 3;
                break;
            case 5:
                coords[0] = 3;
                coords[1] = 6;
                break;
            case 6:
                coords[0] = 6;
                coords[1] = 0;
                break;
            case 7:
                coords[0] = 6;
                coords[1] = 3;
                break;
            case 8:
                coords[0] = 6;
                coords[1] = 6;
                break;
        }
        int[][] group = new int[3][3];
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                group[i][j] = sudoku[(coords[0] + i)][(coords[1] + j)];
            }
        }
        int find = 0;
        for (int i = 0; i < 9; i++) {
            find = 0;
            for (int j = 0; j < 3; j++) {
                for (int x = 0; x < 3; x++) {
                    if (group[j][x] == (i+1)) {
                        find++;
                    }
                }
            }
            if (find > 1) {
                return false;
            }
        }
        return true;
    }
    
    //Metodo che ottiene una stringa a partire da una matrice (9X9)
    public static String getStringMatrice(int[][] matrice){
    	String s="";
    	for (int i=0;i<9;i++){
    		for (int j=0;j<9;j++){
    			s = s+String.valueOf(matrice[i][j]);
    		}
    	}
    	return s;
    }
	
    public static boolean confrontaMatrici(int[][] a, int[][] b){
    	boolean x = true;
    	for (int i=0;i<9;i++){
    		for (int j=0;j<9;j++){
    			if (a[i][j]!=b[i][j]) x = false; 
    		}
    	}
    	return x;
    }
    
    public static void stampaMatrice(int[][] m){
    	for (int i=0;i<9;i++){
    		for (int j=0;j<9;j++){
    			System.out.print(m[i][j]);
    		}
    		System.out.println();
    	}
    }

}
